

#pragma once

// MOOSE includes
#include "SystemBase.h"
#include "ExecuteMooseObjectWarehouse.h"
#include "PerfGraphInterface.h"

// 线性隐式系统求解VFV重构方程
#include "libmesh/linear_implicit_system.h"
#include "libmesh/equation_systems.h"
#include "libmesh/enum_solver_type.h"
#include "libmesh/enum_preconditioner_type.h"



// Forward declarations
template <typename ComputeValueType>
class AuxKernelTempl;
typedef AuxKernelTempl<Real> AuxKernel;
typedef AuxKernelTempl<RealVectorValue> VectorAuxKernel;
class FEProblemBase;
class VFVProblem;
class TimeIntegrator;
class AuxScalarKernel;

// libMesh forward declarations
namespace libMesh
{
template <typename T>
class NumericVector;
}

class Assembly;
/**
 * 定义VFV重构系统，类似于AuxiliarySystem
 *
 */
class ReconstructionSystem : 
	public SystemBase, 
	public PerfGraphInterface
{
public:
  ReconstructionSystem(FEProblemBase & subproblem, const std::string & name);
  virtual ~ReconstructionSystem();

  /**
   * 初始化，被FEProblemBase.init()调用
  */
  void init();
  virtual void initialSetup();
  virtual void timestepSetup();
  virtual void subdomainSetup();
  virtual void residualSetup();
  virtual void jacobianSetup();
  virtual void updateActive(THREAD_ID tid);


  virtual void reinitElem(const Elem* elem, THREAD_ID tid) override ;
  virtual void reinitElemFace(const Elem* elem, unsigned int side, BoundaryID bnd_id, THREAD_ID tid);

  /**
  * 获取libMesh system
  */
  virtual LinearImplicitSystem& sys() { return _sys; }
  virtual System& system() override { return _sys; }
  virtual const System& system() const override { return _sys; }

  /**
 * The solution vector that is currently being operated on.
 * This is typically a ghosted vector that comes in from the Nonlinear solver.
 */
  const NumericVector<Number>* const& currentSolution() const override
  {
	  _current_solution = _sys.current_local_solution.get();
	  return _current_solution;
  }

  const NumericVector<Number>* solutionPreviousNewton() const override { return nullptr;}
  NumericVector<Number>* solutionPreviousNewton() override { return _solution_previous_nl; }

  NumericVector<Number>* solutionUDot() override { return nullptr; }
  NumericVector<Number>* solutionUDotDot() override { return nullptr; }
  NumericVector<Number>* solutionUDotOld() override { return nullptr; }
  NumericVector<Number>* solutionUDotDotOld() override { return nullptr; }
  const NumericVector<Number>* solutionUDot() const override { return nullptr; }
  const NumericVector<Number>* solutionUDotDot() const override { return nullptr; }
  const NumericVector<Number>* solutionUDotOld() const override { return nullptr; }
  const NumericVector<Number>* solutionUDotDotOld() const override { return nullptr; }

  NumericVector<Number>& solutionInternal() const override { return *_sys.solution; }
  NumericVector<Number>& solutionOldInternal() const override
  {
	  return *_sys.solution;
  }
  NumericVector<Number>& solutionOlderInternal() const override
  {
	  return *_sys.solution;
  }


  virtual void serializeSolution();
  virtual NumericVector<Number>& serializedSolution() override;
  virtual void augmentSparsity(SparsityPattern::Graph& /*sparsity*/,
	  std::vector<dof_id_type>& /*n_nz*/,
	  std::vector<dof_id_type>& /*n_oz*/) override;
  /**
   * 为系统增加变量
   * @param type Type of the integrator
   * @param name The name of the integrator
   * @param parameters Integrator params
   */
  virtual void addVariable(const std::string & var_type, const std::string & name, InputParameters & parameters) override ;

  // 在_sys中加入变量
  //void addVariable(const std::string& name, FEType type);

  void solve();

  // 类的变量
protected:
  FEProblemBase & _fe_problem_base;
  //VFVProblem& _vfv_problem;
  MooseMesh& _mesh;
  EquationSystems& _eq;
  LinearImplicitSystem & _sys;
  Assembly& _assembly;
  Order _order;
  FEType _fe_type;
  SolverType _solver_type;
  PreconditionerType _preconditioner_type;

  std::vector<std::vector<MooseVariableFEBase*>> _elem_vars;


  /// solution vector from nonlinear solver
  mutable const NumericVector<Number>* _current_solution;
  /// Serialized version of the solution vector
  NumericVector<Number>& _serialized_solution;
  /// Solution vector of the previous nonlinear iterate
  NumericVector<Number>* _solution_previous_nl;
  /// Time integrator
  std::shared_ptr<TimeIntegrator> _time_integrator;
  /// solution vector for u^dot
  NumericVector<Number>* _u_dot;
  /// solution vector for u^dotdot
  NumericVector<Number>* _u_dotdot;

  /// Old solution vector for u^dot
  NumericVector<Number>* _u_dot_old;
  /// Old solution vector for u^dotdot
  NumericVector<Number>* _u_dotdot_old;
  bool _need_serialized_solution;

  /*
  * 组装重构矩阵和右端项
  */
  friend void assemble_reconstrunction(EquationSystems & es, const std::string & system_name);
public:
  void setOrder(const Order& order) {_order = order;}
  void setFEType(const FEType& type) {_fe_type = type;}
  void setSolverType(const SolverType& type) {_solver_type = type;}
  void setPreconditionerType(const PreconditionerType & type) {_preconditioner_type = type;}


};
